package com.zhang.util;

import org.ehcache.Cache;
import org.ehcache.CacheManager;
import org.ehcache.config.CacheConfiguration;
import org.ehcache.config.builders.CacheConfigurationBuilder;
import org.ehcache.config.builders.CacheManagerBuilder;
import org.ehcache.config.builders.ExpiryPolicyBuilder;
import org.ehcache.config.builders.ResourcePoolsBuilder;
import org.ehcache.config.units.EntryUnit;
import org.ehcache.config.units.MemoryUnit;

import java.time.Duration;
import java.util.List;

/**
 * Ehcache缓存工具类
 *
 * @author zhangshuaiyin
 * @date 2021-01-15 10:04:03
 */
public class EhcacheUtils {
    /**
     * 初始化Ehcache配置
     */
    private static CacheConfiguration<String, String> usesConfiguredInCacheConfig;

    /**
     * 初始化管理器
     */
    private static CacheManager cacheManager;

    private static final String COMMON_CACHE = "CommonCache";

    static {
        init();
    }

    private static void init() {
        if (usesConfiguredInCacheConfig == null) {
            usesConfiguredInCacheConfig = CacheConfigurationBuilder
                    .newCacheConfigurationBuilder(String.class, String.class,
                            ResourcePoolsBuilder.newResourcePoolsBuilder()
                                    .heap(2000L, EntryUnit.ENTRIES)
                                    .offheap(20L, MemoryUnit.MB))
                    .withSizeOfMaxObjectGraph(2000L)
                    .withSizeOfMaxObjectSize(100L, MemoryUnit.KB)
                    //失效时间
                    .withExpiry(ExpiryPolicyBuilder.timeToIdleExpiration(Duration.ofSeconds(300)))
                    .build();
        }

        if (cacheManager == null) {
            cacheManager = CacheManagerBuilder.newCacheManagerBuilder()
                    .withDefaultSizeOfMaxObjectSize(50L, MemoryUnit.KB)
                    .withDefaultSizeOfMaxObjectGraph(2000)
                    .withCache(COMMON_CACHE, usesConfiguredInCacheConfig)
                    .build(true);
        }
    }


    public static Cache<String, String> getCache(String cacheName) {
        return cacheManager
                .getCache(cacheName, String.class, String.class);
    }

    /**
     * 设置缓存
     *
     * @param key   key
     * @param value value
     */
    public static void set(String key, Object value) {
        getCache(COMMON_CACHE).put(key, JsonUtils.toJSONString(value));
    }

    /**
     * 获取缓存
     *
     * @param key   key
     * @param clazz clazz
     * @param <T>   T
     * @return T
     */
    public static <T> T get(String key, Class<T> clazz) {
        return JsonUtils.parseObject(getCache(COMMON_CACHE).get(key), clazz);
    }

    /**
     * 获取缓存
     *
     * @param key key
     * @return cache
     */
    public static String get(String key) {
        return getCache(COMMON_CACHE).get(key);
    }

    /**
     * 获取缓存返回list列表
     *
     * @param key   key
     * @param clazz clazz
     * @param <T>   <T>
     * @return T
     */
    public static <T> List<T> list(String key, Class<T> clazz) {
        return JsonUtils.parseList(getCache(COMMON_CACHE).get(key), clazz);
    }

    /**
     * 移除缓存key
     *
     * @param key key
     */
    public static void remove(String key) {
        getCache(COMMON_CACHE).remove(key);
    }

    /**
     * 缓存清理
     */
    public static void clear() {
        getCache(COMMON_CACHE).clear();
    }

    /**
     * 关闭管理器
     */
    public static void close() {
        cacheManager.close();
    }

    public static void main(String[] args) {
        init();
        set("haha", "哈哈哈");
        String haha = get("haha");
        System.out.println(haha);
    }
}
